// Include system file
#include "r_cg_can.h"

// Include project file
#include "CAN.h"
#include "fet.h"
#include "nvm.h"
#include "control.h"
#include "faults.h"
#include "Main.h"
#include "Switches.h"
#include "Joystick.h"
#include "Serial.h"
#include "Battery.h"
#include "BMS_CAN.h"

#include "RangeExtender.h"
#include "RemoteCtrlCan.h"




structRangeExtenderManualMode stREMM = {0};
unionRangeExtenderOutPut unRE_Out = {0};


#define RE_PowerOnOff stRemoteCtrlCan.unRx0x181.bit.fButtonRangeExtenderStartOrStop
#define RE_RPM		0//增程器转速

#define RE_TASK_300mS	(300/10)
#define RE_TASK_3S	(3000/10)
#define RE_TASK_10S	(10000/10)
#define RE_TASK_20S	(20000/10)
/*
增程启动相关
保持线圈就是熄火线圈
接触器控制

1.启动线圈
2.熄火
3.水泵
4.燃油
5.预热
6.充电接触器控制

启动 启动线圈（MAX3s）+熄火保持+水泵+燃油泵+接触器,3s后如果转速反馈低于800，全部关闭，10s后允许重启
//温度低需要预热

typedef union
{
	UINT8 Bytes[1];
	struct
	{
		UINT8 fStartCoil:1;
		UINT8 fHoldCoil:1;
		UINT8 fWaterPump:1;
		UINT8 fOilPump:1;
		UINT8 fChargeCtrlCoil:1;
		UINT8 fPreHeatCoil:1;
		UINT8 Byte0NC:2;
	}bit;
}unionRangeExtenderOutPut;

*/

void vProcRangeExtenderManualMode(void)//10ms
{
	static UINT8 u8LastStart=0;
	switch(stREMM.enRE_State)
	{
		case RE_StateIdle:
			if(stREMM.enRE_StateLast != stREMM.enRE_State)
			{
				stREMM.enRE_StateLast = stREMM.enRE_State;
				//计时清空
				stREMM.u16StartCoilRunTime=0;
				stREMM.u16HoldCoilOffTime=0;
				stREMM.u16OidPumpOffTime=0;
				stREMM.u16RpmFitterTime=0;
				stREMM.u16RangeExtenderPowerOnTimeCnt=0;
				stREMM.u16ReStartDelayCnt=0;
			}
			unRE_Out.Bytes[0]=0X00;//
			if(RE_PowerOnOff==1&&u8LastStart==0)
			{
				stREMM.enRE_State = RE_StateStarting;
			}
			
		break;
		case RE_StateStarting:
			if(stREMM.enRE_StateLast != stREMM.enRE_State)
			{
				stREMM.enRE_StateLast = stREMM.enRE_State;
				stREMM.u16StartCoilRunTime=0;//启动线圈输出最长输出不超过3秒 ，如果增程器在3秒内启动成功，则输出小于3秒
				/*
				如果十秒内增程器转速>800转且持续300毫秒以
				上，则增程器启动成功，否则启动失败。增程器
				持续启动时间最长为10秒
				*/
				stREMM.u16RangeExtenderPowerOnTimeCnt=0;
			}
			unRE_Out.bit.fHoldCoil=1;
			unRE_Out.bit.fWaterPump=1;
			unRE_Out.bit.fOilPump=1;
			unRE_Out.bit.fChargeCtrlCoil=1;
			if(stREMM.u16StartCoilRunTime<RE_TASK_3S)//最多启动线圈3s
			{
				stREMM.u16StartCoilRunTime++;
				unRE_Out.bit.fStartCoil=1;
			}
			else
			{
				unRE_Out.bit.fStartCoil=0;
			}
			if(stREMM.u16RangeExtenderPowerOnTimeCnt<RE_TASK_10S)//启动时间最多10s
			{
				stREMM.u16RangeExtenderPowerOnTimeCnt++;
				if(RE_RPM>800)
				{
					if(stREMM.u16RpmFitterTime<RE_TASK_300mS)
					{
						stREMM.u16RpmFitterTime++;
					}
					else
					{
						stREMM.enRE_State = RE_StateStartOk;
					}
				}
				else
				{
					stREMM.u16RpmFitterTime = 0;
				}
			}
			else
			{
				stREMM.enRE_State = RE_StateStartErr;
			}
		break;
		case RE_StateStartOk:
			if(stREMM.enRE_StateLast != stREMM.enRE_State)
			{
				stREMM.enRE_StateLast = stREMM.enRE_State;
				unRE_Out.bit.fStartCoil=0;
			}
			if(RE_PowerOnOff==1&&u8LastStart==0)
			{
				stREMM.enRE_State = RE_StateOffing;
				stREMM.u16HoldCoilOffTime = 0;
			}
		break;
		case RE_StateStartErr:
			if(stREMM.enRE_StateLast != stREMM.enRE_State)
			{
				stREMM.enRE_StateLast = stREMM.enRE_State;
				stREMM.u16ReStartDelayCnt = 0;
			}
			unRE_Out.Bytes[0]=0X00;//
			if(stREMM.u16ReStartDelayCnt<RE_TASK_20S)
			{
				stREMM.u16ReStartDelayCnt++;
			}
			else
			{
				stREMM.enRE_State = RE_StateIdle;
			}
		break;
		case RE_StateOffing:
			if(stREMM.enRE_StateLast != stREMM.enRE_State)
			{
				stREMM.enRE_StateLast = stREMM.enRE_State;
				stREMM.u16HoldCoilOffTime=0;
			}
			unRE_Out.Bytes[0]=0X00;//
			if(stREMM.u16HoldCoilOffTime <RE_TASK_20S)//持续20s关闭保持线圈
			{
				stREMM.u16HoldCoilOffTime++;
			}
			else
			{
				if(RE_RPM<10)
				{
					stREMM.enRE_State = RE_StateIdle;
				}
			}			
		break;
		default:
			stREMM.enRE_State = RE_StateIdle;
		break;
	}
	u8LastStart = RE_PowerOnOff;
}

